<?php

namespace Services\Fenxiao;

use Common\Model\Fenxiao\FenxiaoUserRecordModel;
use Common\Model\Log\LogModel;
use Common\Model\User\UserVipLogModel;
use Services\BaseService;
use Services\Fenxiao\Exceptions\FenxiaoException;
use Services\Log\LogService;
use Services\Security\SecurityService;
use Services\User\UserService;

class FenxiaoService extends BaseService
{
    const MAX_FIRST_REWARD_VALID_DAY = 30;

    /** @var FenxiaoUserRecordModel $model */
    private $model;

    public function __construct()
    {
        $this->model = new FenxiaoUserRecordModel();
    }

    public function bind()
    {
        $result = false;
        try {
            $parentUserId = $this->getParam('parent_user_id');
            $parentUserId = SecurityService::decryptData(urldecode($parentUserId));
            $userId = $this->getParam('user_id');//有上级则不能进行绑定
            if (!$parentUserId) {
                throw new FenxiaoException('上级用户id不能为空');
            }
            if ($parentUserId == $userId) {
                throw new FenxiaoException('自身不能绑定自己');
            }

            $record = $this->model->where(['user_id' => $userId])->find();
            if ($record) {
                throw new FenxiaoException('该用户已绑定过上级');
            }
            $result = $this->model->add([
                'user_id' => $userId,
                'parent_user_id' => $parentUserId,
                'first_reward_valid' => FenxiaoUserRecordModel::FIRST_REWARD_VALID,
                'first_reward_grant' => FenxiaoUserRecordModel::FIRST_REWARD_NOT_GRANT,
                'created_at' => get_now_date(),
                'updated_at' => get_now_date(),
            ]);
            if ($result) {
                //清除所有的失效态记录
                $this->model->where(['user_id' => $userId])->where('deleted_at is not null')->delete();
                // (new UserService())->openVip($parentUserId, 1, UserVipLogModel::CHANNEL_FENXIAO);
            }
        } catch (\Exception $e) {
            LogService::writeWithDb(array_merge($this->getParams(), format_exception($e)), $e->getMessage(), LogModel::FENXIAO_BIND);
        }
        return $result;
    }

    /**
     * 获取下级用户列
     * @return void
     */
    public function getSubordinateList()
    {
        $query = M()->table('user_fenxiao_records as fx')
            ->join('user as u on fx.user_id = u.id', 'left')
            ->join('user_card_list as ucard on ucard.user_id = u.id', 'left')
            ->field('u.id,u.user_nickname,u.user_headimg,ucard.jianjie,ucard.zhiye_label,fx.updated_at')
            ->where([
                'fx.parent_user_id' => $this->getParam('user_id'),
            ]);
        $pageLimit = $this->getParam('page_limit', 15);
        $page = $this->getParam('page', 1);
        //0-代表查询有效用户，1-查询解绑的用户
        $type = $this->getParam('type', FenxiaoUserRecordModel::FIRST_REWARD_VALID);
        $query = $query->where('fx.first_reward_valid = ' . $type)->order('fx.id desc');
        $users = $query->limit(($page - 1) * $pageLimit, $pageLimit)->select();
        foreach ($users as $idx => $user) {
            $users[$idx]['jianjie'] = $user['jianjie'] ? $user['jianjie'] : '';
            $users[$idx]['labels'] = $user['jianjie'] ? explode(',', $user['zhiye_label']) : [];
        }
        return $users;
    }

    /**
     * 标记首次奖励为失效
     * @param $id
     * @param $attributes
     * @return true
     */
    private function setFirstRewardInvalid($id, $attributes = [])
    {
        $updateData = array_merge([
            'status' => FenxiaoUserRecordModel::FIRST_REWARD_INVALID
        ], $attributes);
        $this->model->where('id', $id)->save($updateData);
        return true;
    }

    public function getRecordByUserId($userId)
    {
        return $this->model->where('user_id', $userId)->find();
    }

    /**
     * 自动标记满足条件的首次奖励为失效
     * @return void
     */
    public function firstRewardInvalid()
    {
        $records = $this->model->where([
            'first_reward_valid' => FenxiaoUserRecordModel::FIRST_REWARD_VALID,
        ])
            ->limit(200)
            ->select();
        $now = time();
        foreach ($records as $record) {
            $recordCreateTime = strtotime($record['created_at']);
            //计算出创建时间距离当前时间的天数
            $differenceDay = calculate_days_difference($recordCreateTime, $now);
            //如果大于30天，则将first_reward_valid置为0
            if ($differenceDay >= self::MAX_FIRST_REWARD_VALID_DAY) {
                $this->setFirstRewardInvalid($record['id']);
            }
        }
        return true;
    }

    /**
     * 依据用户id发放邀请人首次奖励
     * @return void
     */
    public function firstRewardGrant($userId)
    {
        try {
            $record = $this->getRecordByUserId($userId);
            if (empty($record)) {
                throw new FenxiaoException('该用户没有绑定上级');
            }
            //查询出已经成功发放奖励的个数
            $rewardGrantCount = $this->model->where([
                'parent_user_id' => $record['parent_user_id'],
                'first_reward_grant' => FenxiaoUserRecordModel::FIRST_REWARD_GRANT,
                'user_is_pay' => FenxiaoUserRecordModel::USER_IS_PAY
            ])->count();
            //依据数量拿到会员天数的发放规则
            $vipDay = $this->getSendVipDayByRewardGrantCount($rewardGrantCount);
            if (!$vipDay) {
                $state = (new UserService())->openVip($record['parent_user_id'], $vipDay, UserVipLogModel::CHANNEL_FENXIAO);
                //标记首次奖励已经完成
                if($state){
                    $this->model->where([
                        'id'=>$record['id']
                    ])->save([
                        'first_reward_grant' => FenxiaoUserRecordModel::FIRST_REWARD_GRANT,
                        'user_is_pay' => FenxiaoUserRecordModel::USER_IS_PAY
                    ]);
                }
            }
        } catch (FenxiaoException $e) {
            LogService::writeWithDb(array_merge($this->getParams(), format_exception($e)), $e->getMessage(), LogModel::FENXIA_REWARD);
        }
        return true;
    }

    private function getSendVipDayByRewardGrantCount($rewardGrantCount)
    {
        $vipDay = 0;
        if ($rewardGrantCount == 2) {
            $vipDay = 30;
        }
        if ($rewardGrantCount ==5) {
            $vipDay = 365;
        }
        if ($rewardGrantCount == 10) {
            $vipDay = 30000;
        }

        return $vipDay;
    }

}
